﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twitter.Tests;
using NUnit.Framework;
using Twitter;
using FriendsNearby.Services;
using Moq;
using FriendsNearby.Services.Entities;
using InSTEDD.Labs.Geo;

namespace FriendsNearbyBot.Tests
{
    [TestFixture]
    public class PingProcessorFixture : TestBase
    {
        [Test]
        public void ShouldSendMeessageIfLastUpdateIsNotKnown()
        {
            FacadeWithMocks services = new FacadeWithMocks();
            services.MockUsersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtesta")).Returns("1234");
            services.MockLocationService.Expect(x => x.GetLastLocationInfo("1234")).Returns( () => null );

            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtesta");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            PingProcessor processor = new PingProcessor(services, CreateMessageBuilder());
            Message message = CreateMessage("ping", "fnbtesta", "fnb");

            Assert.IsTrue(processor.CanProcess(message));
            var runNext = processor.Process(bot, message);
            Assert.AreEqual(RunNextProcessor.No, runNext);

            string text = "Service is running. There is no previous location. This message was sent at";

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            AssertString.StartsWith(text, user.Messages.GetAll().First().Text);
            AssertString.EndsWith("UTC.", user.Messages.GetAll().First().Text);
        }

        [Test]
        [Ignore("Country Border Config")] // TODO fix configuration
        public void ShouldSendLastUpdateWithCountryName()
        {
            FacadeWithMocks services = new FacadeWithMocks();
            services.MockUsersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtesta")).Returns("1234");
            services.MockLocationService.Expect(x => x.GetLastLocationInfo("1234"))
                .Returns(new UserInfo() { FacebookUserId = "1234", LastLocationUpdate = DateTime.Now, Location = new LatLong(38, -120) });

            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtesta");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            PingProcessor processor = new PingProcessor(services, CreateMessageBuilder());
            Message message = CreateMessage("ping", "fnbtesta", "fnb");

            Assert.IsTrue(processor.CanProcess(message));
            var runNext = processor.Process(bot, message);
            Assert.AreEqual(RunNextProcessor.No, runNext);

            string location = "United States";
            string updated = "now";
            string text = string.Format("Service is running. Last location update was in {0} {1}. This message was sent at", location, updated);

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            AssertString.StartsWith(text, user.Messages.GetAll().First().Text);
            AssertString.EndsWith("UTC.", user.Messages.GetAll().First().Text);
        }

        [Test]
        public void ShouldSendLastUpdate()
        {
            FacadeWithMocks services = new FacadeWithMocks();
            services.MockUsersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtesta")).Returns("1234");
            services.MockLocationService.Expect(x => x.GetLastLocationInfo("1234"))
                .Returns(new UserInfo() { FacebookUserId = "1234", LastLocationUpdate = DateTime.Now, Location = new LatLong(44, 33) });

            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtesta");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            PingProcessor processor = new PingProcessor(services, CreateMessageBuilder());
            Message message = CreateMessage("ping", "fnbtesta", "fnb");

            Assert.IsTrue(processor.CanProcess(message));
            var runNext = processor.Process(bot, message);
            Assert.AreEqual(RunNextProcessor.No, runNext);

            string location = "44 33";
            string updated = "now";
            string text = string.Format("Service is running. Last location update was in {0} {1}. This message was sent at", location, updated);

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            AssertString.StartsWith(text, user.Messages.GetAll().First().Text);
            AssertString.EndsWith("UTC.", user.Messages.GetAll().First().Text);            
        }

        

        class FacadeWithMocks : FriendsNearbyFacade
        {
            public Mock<IUsersService> MockUsersService = new Mock<IUsersService>();
            public Mock<ILocationService> MockLocationService = new Mock<ILocationService>();

            protected override IUsersService BuildUsersService()
            {
                return MockUsersService.Object;
            }

            protected override ILocationService BuildLocationService(IPeopleNearbyService peopleNearbyService)
            {
                return MockLocationService.Object;
            }
        }
    }

}
